package com.desaysv.svhttp;

import android.util.Log;

import com.desaysv.svhttp.handler.IHandler;

import java.lang.reflect.Constructor;
import java.util.Arrays;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author linzi
 * @version 1.0
 * @date 2022-7-19
 * 网络请求代理器，代理所有的IHandler对象
 * @since 2022-7-19
 */
public final class SVHttpProxy {
    /**
     * 代理对象缓存池
     */
    private final ConcurrentHashMap<String, IHandler> mProxyPool = new ConcurrentHashMap<>();
    /**
     * 日志TAG
     */
    private static final String TAG = "[SVHttpProxy]";

    /**
     * 构造函数
     */
    private SVHttpProxy() {

    }

    /**
     * 单例对象
     */
    private static final class MInstanceHolder {
        /**
         * 单例
         */
        static final SVHttpProxy INSTANCE = new SVHttpProxy();
    }

    /**
     * 获取单例对象
     *
     * @return SVHttpProxy
     */
    public static SVHttpProxy getFactory() {
        return MInstanceHolder.INSTANCE;
    }

    /**
     * 通过public的构造函数来代理对象
     *
     * @param t   代理对象class
     * @param <T> 父类
     * @return IHandler对象
     */
    private <T extends IHandler> IHandler getPublic(Class<T> t) {
        IHandler temp = null;
        try {
            temp = t.newInstance();
            mProxyPool.put(t.getName(), temp);
        } catch (Exception e) {
            Log.e(TAG, "public init fail!!!");
        }
        return temp;
    }

    /**
     * 通过private的构造函数来代理对象
     *
     * @param t   代理对象class
     * @param <T> 父类
     * @return IHandler对象
     */
    private <T extends IHandler> IHandler getPrivate(Class<T> t) {
        IHandler temp = null;
        try {
            Constructor<?>[] conns = t.getDeclaredConstructors();
            IHandler iproxy = null;
            for (Constructor<?> conn : conns) {
                try {
                    conn.setAccessible(true);
                    iproxy = (IHandler) conn.newInstance();
                    break;
                } catch (Exception e) {
                    Log.e(TAG, "private method init fail!!!");
                }
            }
            temp = iproxy;
            assert temp != null;
            mProxyPool.put(t.getName(), temp);
        } catch (RuntimeException e) {
            throw e;
        } catch (Exception e) {
            Log.e(TAG, "private init fail!!!");
        }
        return temp;
    }

    /**
     * 构造代理的对象实例
     *
     * @param t   代理对象class
     * @param <T> 父类
     * @return 代理对象实例
     */
    public <T extends IHandler> IHandler getProxy(Class<T> t) {
        Class[] allFace = t.getInterfaces();
        if (!Arrays.asList(allFace).contains(IHandler.class)) {
            return null;
        }
        IHandler temp = mProxyPool.get(t.getName());
        if (temp == null) {
            Log.e(TAG, t.getName());
            synchronized (SVHttpProxy.class) {
                temp = mProxyPool.get(t.getName());
                if (temp == null) {
                    temp = getPublic(t);
                }
                //私有构造函数
                if (temp == null) {
                    temp = getPrivate(t);
                }
            }
        }
        return temp;
    }

    /**
     * 检查是否初始化
     *
     * @param t   检查对象
     * @param <T> 检查类型
     * @return true/false
     */
    public <T> boolean checkInit(Class<T> t) {
        return mProxyPool.get(t) != null;
    }
}
